#ifndef MINION_H
#define MINION_H

#include <QPixmap>
#include "definitions.h"

class Minion
{
    /* parameters (these values remain constant for the same minion) */
    QString PlayerName;

    int Team = 1;
    int PowerFactor = 0;
    int ArmorFactor = 0;
    double HealthFactor = 0;
    double FireRateFactor = 0;
    int SightFactor = 0;
    int RangeFactor = 0;

    double SpeedFactor = 0;
    double BulletSpeedFactor = 0;
    double RotationSpeedFactor = 0.0;
    double TurretRotationSpeedFactor = 0.0;

    int Size = 0;

    QPixmap *PictureBase = nullptr;
    QPixmap *PictureTurret = nullptr;
    QPixmap *PictureBullet = nullptr;

    Skill *Ability1 = nullptr;
    Skill *Ability2 = nullptr;
    Skill *Ability3 = nullptr;

    /* stats (these values change by their factor only when new level is gained) */
    int Level = 1;

    int Power = 0;
    int Armor = 0;
    double MaxHealth = 0;
    double FireRate = 0; // shots/second
    int Sight = 0;
    int Range = 0;

    double Speed = 0; // pixels/second
    double BulletSpeed = 0; // pixels/second
    double RotationSpeed = 0.0; // P/second, where P=percent of full circle, in range of 0.0 to 1.0
    double TurretRotationSpeed = 0.0; // P/second

    /* state (these values may change any time during game)*/
    double Health = 0;
    unsigned int Experience = 0;
    unsigned int TicksCounter = 0; // counts number of ticks since last full second
    int TimeToRespawn = 0;

    MinionFlags Flags = MinionFlags::MINION_NONE;

    double X = 0.0;
    double Y = 0.0;
    double Orientation = 0.0; // from 0.0 to 1.0; 0.0=north, 0.25=east, etc.
    double TurretOrientation = 0.0; // from 0.0 to 1.0; 0.0=north, 0.25=east, etc.
    double DestinationX = 0;
    double DestinationY = 0;
    Minion *DestinationMinion = nullptr;
    int Cooldown = 0; // can only shoot when Cooldown is zero, each shoot sets Cooldown to Firerate value, each tick decreases it by one

    Minion *NextMinion = nullptr; // next bullet in the list

private:
    Skill *LoadAbility(const QString &Ability);
    void UpdateDestinationPoint();
    inline void UpdateDestinationMinion();
    inline void UpdateDesiredTurretOrientation(double &DesiredTurretOrientation,
                                            int &DestinationMinionX, int &DestinationMinionY);
    void RotateAndMove();
    void Respawn();
    void GainExperience();
    void Regenerate();

public:
    Minion(const QString &Filename, double DefaultOrientation);
    void MoveTick();
    void ShootTick();
    void Damage(int Power, BulletFlags BFlags);
    void NewDestination(int NewX, int NewY);
    void NewTarget(Minion *TargetMinion, bool Follow = true);
    void MinionRemovalNotification(Minion *RemovedMinion);
    void SetTeam(int team);
    void Spawn();

    inline double GetX() { return X; }
    inline double GetY() { return Y; }
    inline double GetOrientation() { return Orientation; }
    inline double GetTurretOrientation() { return TurretOrientation; }
    inline QString &GetPlayerName() { return PlayerName; }
    inline int GetTeam() { return Team; }
    inline int GetLevel() { return Level; }
    inline int GetSize() { return Size; }
    inline int GetPower() { return Power; }
    inline int GetArmor() { return Armor; }
    inline double GetFireRate() { return FireRate; }
    inline int GetRange() { return Range; }
    inline double GetSpeed() { return Speed; }
    inline int GetSight() { return Sight; }
    inline unsigned int GetExperience() { return Experience; }
    inline double GetHealth() { return Health; }
    inline double GetMaxHealth() { return MaxHealth; }
    inline int GetTimeToRespawn() { return TimeToRespawn; }
    inline Minion *GetNextMinion() { return NextMinion; }
    inline Minion *GetCurrentTarget() { return DestinationMinion; }
    inline bool IsDead() { return Health < 1.0; }
    inline bool IsInvisible() { return Flags & INVISIBLE; }
    inline bool IsMini() { return Flags & IS_MINI; }
    inline bool IsStructure() { return Flags & (IS_TOWER|IS_BASE); }
    inline bool IsBase() { return Flags & IS_BASE; }
    inline bool IsPlayer() { return !(Flags & (IS_TOWER|IS_BASE|IS_MINI)); }
    inline bool IsWreck() { return Flags & IS_WRECK; }
    inline bool IsRespawning() { return Flags & IS_RESPAWNING; }
    inline QPixmap *GetBaseSprite() { return PictureBase; }
    inline QPixmap *GetTurretSprite() { return PictureTurret; }

    friend class Engine;
};

#endif // MINION_H
